﻿using System;
using System.Data;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Eneta.Portal.Common;
using Eneta.Portal.Common.Helpers;
using Eneta.Portal.Controls;
using Microsoft.SharePoint;


namespace Eneta.Portal.NewsAndBlogs.Controls
{
    public class NewsAndBlogsWebPartControl : UserControl
    {
        protected Repeater _informationArea;
        protected Repeater _newsWithSummary;
        protected Repeater _newsWithTitle;
        protected Repeater _blogBoxFirst;
        protected Repeater _blogBox;
        protected Repeater _tools;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            _informationArea.ItemDataBound += InformationAreaItemDataBound;
            _newsWithSummary.ItemDataBound += InformationAreaItemDataBound;
        }

        protected void InformationAreaItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;
            var item = (DataRowView)e.Item.DataItem;

            var keywordsField = (HtmlGenericControl)e.Item.FindControl("keywordsField");
            var dateAndBlogField = (HtmlGenericControl)e.Item.FindControl("dateAndBlogField");

            if (item["Keywords1"] != null)
            {
                keywordsField.InnerText = GetKeywords(item["Keywords1"].ToString());                
            }
            else
                keywordsField.InnerText = string.Empty;

            var bodyField = (HtmlGenericControl) e.Item.FindControl("bodyField");
            if (bodyField != null)
            {
                var body = item["Summary"].ToString();
                body = RegExHelper.RemoveHtmlTags(body).Trim();
                if (body.StartsWith("&#160;"))
                    body = body.Substring(5).Trim();
                bodyField.InnerText = body;
            }
            dateAndBlogField.InnerText = string.Empty;
            if (item["PublishDate"]!=null)
            {
                try
                {
                    Logger.LogInfo("BU: PublishDate is not null", "");
                    var publishDate = DateTime.Parse(item["PublishDate"].ToString());
                    dateAndBlogField.InnerText = publishDate.ToString("dd.MM.yyyy");
                }
                catch
                {
                    dateAndBlogField.InnerText = item["PublishDate"].ToString(); // string.Empty;
                }
            }
            else if(item["Created"] != null)
            {
                var publishDate = DateTime.Parse(item["Created"].ToString());
                dateAndBlogField.InnerText = publishDate.ToString("dd.MM.yyyy");                
            }

            if (item["Feed"] != null)
            {
                if (!string.IsNullOrEmpty(dateAndBlogField.InnerText))
                    dateAndBlogField.InnerText += " | ";
                dateAndBlogField.InnerText += item["Feed"].ToString();
            }
            else
            {
                if (!string.IsNullOrEmpty(dateAndBlogField.InnerText))
                    dateAndBlogField.InnerText += " | ";
                dateAndBlogField.InnerText += "ENETA";
            }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            var siteId = SPContext.Current.Site.ID;
            if (SPContext.Current.Web.CurrentUser != null)
            {
                var blogPromo = FindControl("BlogPromo") as HtmlDisplayControl;
                if (blogPromo != null)
                    blogPromo.Visible = false;
            }
            var sec = new SPSecurity.CodeToRunElevated(delegate
                       {
                           using (var site = new SPSite(siteId))
                           {
                               using (var blogsWeb = site.OpenWeb("/uudised/blogid/"))
                               {
                                   var blogs = GetNewestBlogs(blogsWeb);
                                   if (blogs != null)
                                   {
                                       if (blogs.Rows.Count != 0 && !IsPostBack)
                                       {
                                           var firstBlogs = GetBlogWithSummary(blogs, 0, 1);
                                           if (firstBlogs.Rows.Count >= 0)
                                           {
                                               _informationArea.DataSource = firstBlogs;
                                               _informationArea.DataBind();

                                               var secondBlogs = GetBlogWithSummary(blogs, 2, 6);
                                               if (secondBlogs.Rows.Count > 0)
                                               {
                                                   _blogBoxFirst.DataSource = secondBlogs;
                                                   _blogBoxFirst.DataBind();

                                                   var thirdBlogs = GetBlogWithSummary(blogs, 7, 11);
                                                   if (thirdBlogs.Rows.Count > 0)
                                                   {
                                                       _blogBox.DataSource = thirdBlogs;
                                                       _blogBox.DataBind();
                                                   }
                                               }
                                           }
                                       }
                                   }

                               }

                               using (var newsWeb = site.OpenWeb("/uudised/teated/"))
                               {
                                   var news = GetNews(newsWeb);
                                   
                                   if (news == null)
                                   {
                                       Logger.LogInfo("OnLoad(): news is null", GetType().ToString());
                                       return;
                                   }                                  

                                   if (news.Rows.Count != 0)
                                   {
                                       try
                                       {
                                           _newsWithSummary.DataSource = GetNewsWithSummary(news, 1);
                                           _newsWithSummary.DataBind();
                                       }
                                       catch(Exception ex)
                                       {
                                           Logger.LogInfo("OnLoad(): Error binding news", GetType().ToString());
                                           Logger.LogException(ex);
                                       }
                                       _newsWithTitle.DataSource = GetNewsWithTitle(news, 1, 6);
                                       _newsWithTitle.DataBind();
                                   }
                               }
                           }
                       });
            SPSecurity.RunWithElevatedPrivileges(sec);
        }

        private static DataTable GetNewsWithSummary(DataTable news, int count)
        {
            var result = new DataTable();
            result.Columns.Add("Title", typeof(string));
            result.Columns.Add("Summary", typeof(string));
            result.Columns.Add("URL", typeof(string));
            result.Columns.Add("Keywords1", typeof(string));
            result.Columns.Add("Feed", typeof(string));
            result.Columns.Add("CommentsCount", typeof(string));
            result.Columns.Add("PublishDate", typeof(string));
            for (var i = 0; i < count; i++)
            {
                if (news.Rows.Count <= i)
                    break;
                var row = news.Rows[i];
                var resultRow = result.NewRow();
                resultRow["Title"] = row["Title"].ToString();
                var summary = row["PublishingPageContent"].ToString();
                summary = RegExHelper.RemoveHtmlTags(summary);
                if (summary.Length > 255)
                    summary = summary.Substring(0, 255) + "...";
                resultRow["Summary"] = summary;
                if (row["RealAuthor"] != null)
                {
                    resultRow["Feed"] = row["RealAuthor"].ToString();
                }
                else
                {
                    resultRow["Feed"] = "ENETA";
                }
                resultRow["URL"] = "/uudised/teated/Lehed/" + row["FileLeafRef"];
                resultRow["Keywords1"] = row["Keywords1"];
                resultRow["CommentsCount"] = row["CommentsCount"];
                resultRow["PublishDate"] = row["Created"];
                result.Rows.Add(resultRow);
            }
            return result;
        }

        private static DataTable GetNewsWithTitle(DataTable news, int start, int count)
        {
            var result = new DataTable();
            result.Columns.Add("Title", typeof(string));
            result.Columns.Add("Summary", typeof(string));
            result.Columns.Add("URL", typeof(string));
            result.Columns.Add("CommentsCount",typeof(string));
            for (var i = start; i < count; i++)
            {
                if (news.Rows.Count <= i)
                    break;
                var row = news.Rows[i];
                var resultRow = result.NewRow();
                resultRow["Title"] = row["Title"].ToString();
                var summary = row["Comments"].ToString();
                summary = RegExHelper.RemoveHtmlTags(summary);
                if (summary.Length > 255)
                    summary = summary.Substring(0, 255) + "...";
                resultRow["Summary"] = summary;
                resultRow["URL"] = "/uudised/teated/Lehed/" + row["FileLeafRef"];
                resultRow["CommentsCount"] = row["CommentsCount"].ToString();
                result.Rows.Add(resultRow);
            }
            return result;
        }

        private static DataTable GetBlogWithSummary(DataTable allBlogs, int start, int end)
        {
            var result = new DataTable();
            result.Columns.Add("Title");
            result.Columns.Add("Summary");
            result.Columns.Add("Keywords1");
            result.Columns.Add("PublishDate");
            result.Columns.Add("Feed");
            result.Columns.Add("CommentsCount", typeof(string));
            result.Columns.Add("URL", typeof(string));

            if (start > allBlogs.Rows.Count - 1)
                return result;

            if (allBlogs.Rows.Count == 0)
                return result;

            for (var i = start; i <= end; i++)
            {
                if (i > allBlogs.Rows.Count - 1)
                    break;
                var row = result.NewRow();
                row["Title"] = allBlogs.Rows[i]["Title"];

                var summary = allBlogs.Rows[i]["PublishingPageContent"].ToString();
                if(!string.IsNullOrEmpty(summary))
                {
                    summary = summary.Replace("[...]", string.Empty);
                    if (summary.Length > 255)
                    {
                        summary = summary.Substring(0, 255) + "...";
                    }
                }

                row["Summary"] = summary;

                row["PublishDate"] = allBlogs.Rows[i]["PublishDate"];
                row["Keywords1"] = allBlogs.Rows[i]["Keywords1"];
                row["Feed"] = allBlogs.Rows[i]["Feed"];


                row["CommentsCount"] = allBlogs.Rows[i]["CommentsCount"];
                row["URL"] = "/uudised/blogid/Lehed/" + allBlogs.Rows[i]["FileLeafRef"];
                result.Rows.Add(row);
            }

            return result;
        }

        private static DataTable GetNewestBlogs(SPWeb web)
        {
            var list = web.Lists["Lehed"];

            var items = GetFeedEntriesFrom(list, 12);
            if (items == null)
                return null;

            var table = items.GetDataTable();
            if (table == null)
                return table;
            table.Columns.Add("CommentsCount", typeof(string));
            table.Columns.Add("Feed", typeof(string));
            var commentsList = web.Lists["FeedEntriesComments"];
            foreach(DataRow dr in table.Rows)
            {
                var commentsQueryString = "<Where><Eq><FieldRef Name='FeedEntry' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
                commentsQueryString = string.Format(commentsQueryString, dr["ID"]);

                var commentsQuery = new SPQuery { Query = commentsQueryString };

                var commentItems = commentsList.GetItems(commentsQuery);
                if (commentItems.Count > 0)
                    dr["CommentsCount"] = " (" + commentItems.Count + ")";

                var blogValue = new SPFieldLookupValue(dr["Blog"].ToString());
                //var blogItem = list.GetItemById(blogValue.LookupId);
                dr["Feed"] = blogValue.LookupValue;
            }

            //var queryString = "<Where>";
            //queryString += "<Eq><FieldRef Name='ID' /><Value Type='int'>{0}</Value></Eq>";
            //queryString += "</Where>";

            //var query = new SPQuery {Query = queryString, RowLimit = 1};
            return table;
        }

        private static DataTable GetNews(SPWeb web)
        {
            var list = web.Lists["Lehed"];
            var query = new SPQuery();
            query.Query = "<Where><And><Eq><FieldRef Name='_ModerationStatus' /><Value Type='ModStat'>Kinnitatud</Value></Eq><Eq><FieldRef Name='ContentType'/><Value Type='Text'>Uudis</Value></Eq></And></Where><OrderBy><FieldRef Name='Created' Ascending='False'/></OrderBy>";
            query.RowLimit = 6;
            var items = list.GetItems(query);
            DataTable table = items.GetDataTable();
            if (table == null)
            {
                table = new DataTable();
                return new DataTable();
            }
            
            table.Columns.Add("CommentsCount", typeof (string));

            foreach (DataRow dr in table.Rows)
            {
                var commentsQueryString = "<Where><Eq><FieldRef Name='NewsPage' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
                commentsQueryString = string.Format(commentsQueryString, dr["ID"]);

                var commentsQuery = new SPQuery {Query = commentsQueryString};

                var commentItems = web.Lists["Comments"].GetItems(commentsQuery);
                if (commentItems.Count > 0)
                    dr["CommentsCount"] = " (" + commentItems.Count + ")";
            }
            return table;
        }

        private static SPListItemCollection GetFeedEntriesFrom(SPList list, uint resultCount)
        {
            var query = new SPQuery();
            //TODO: Read Approved value form SP resources
            query.Query = "<Where><And><Eq><FieldRef Name='_ModerationStatus'/><Value Type='ModStat'>Kinnitatud</Value></Eq>";
            query.Query += "<Eq><FieldRef Name='ContentType'/><Value Type='Text'>BlogEntry</Value></Eq>";
            query.Query += "</And></Where>";
            query.Query += "<OrderBy><FieldRef Name='PublishDate' Ascending='False'/></OrderBy>";
            query.RowLimit = resultCount;
            return list.GetItems(query);
        }

        private static string GetKeywords(string value)
        {
            if (string.IsNullOrEmpty(value))
                return string.Empty;

            var parts = value.Split(new[] {";#"}, StringSplitOptions.RemoveEmptyEntries);
            var keywords = string.Empty;

            for (var i = 0; i < parts.Length; i++)
                if (i == 0 || i % 2 == 0)
                    keywords += ", " + parts[i];

            if (keywords.Length > 0)
                keywords = keywords.Substring(1).Trim();

            return keywords;
        }
    }
}